// ProductStockService.java
package edu.del.springbootredisbusinesspractice.service;

import edu.del.springbootredisbusinesspractice.service.impl.CacheService;
import edu.del.springbootredisbusinesspractice.service.repository.ProductStockRepository;
import edu.del.springbootredisbusinesspractice.utils.cachekey.CacheConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.support.ResourceScriptSource;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
@Order(1)
public class ProductStockService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private ProductStockRepository stockRepository;

    @Autowired
    private CacheService cacheService; // 保留，用于更新本地缓存

    /**
     * 扣减库存并同步更新本地缓存
     */
    public Long decrementStockAndUpdateLocalCache(int productId, int count) {
        // 1. 直接操作 Redis 扣减库存
        Long newStock = stockRepository.decrementStockInRedis(productId, count);

        // 2. 更新本地缓存
        cacheService.updateStockInLocalCache(productId, newStock);

        return newStock;
    }

    /**
     * 恢复库存并同步更新本地缓存
     */
    public void incrementStockAndUpdateLocalCache(int productId, int count) {
        // 1. 恢复库存
        stockRepository.incrementStockInRedis(productId, count);

        // 2. 从缓存中获取库存
        Long newStock = stockRepository.getStockFromRedis(productId);

        // 3. 更新本地缓存
        cacheService.updateStockInLocalCache(productId, newStock);
    }


    /**
     * 使用 lua 脚本扣减库存
     *
     * @param productId 商品 ID
     * @param count     扣减数量
     * @return 扣减后的库存
     */
    public Long decrementStockWithLuaScript(int productId, int count) {
        // 创建 lua 脚本需要的 keys 集合
        // 由于 redis 引擎 接收 key 是一个集合
        // 因此只有 一个 key 也要封装为集合对象
        List<String> keys = Collections.singletonList(String.format(CacheConstants.STOCK_KEY_PREFIX, productId));
        // 创建 RedisScript（redis 脚本执行器）并设置lua脚本的文件位置
        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
        redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/stock.lua")));
        redisScript.setResultType(Long.class);
        // 执行 lua 脚本
        return redisTemplate.execute(redisScript, keys, count);
    }
}